package com.uni.interceptor;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.uni.jjwt.CheckToken;
import com.uni.jjwt.JwtUtil;
import com.uni.jjwt.LoginToken;
import com.uni.service.impl.UserService;
import com.uni.support.MyException;
import com.uni.support.ThreadLocalUser;
import com.uni.common.entity.User;

import io.jsonwebtoken.Claims;

public class AuthenticationInterceptor implements HandlerInterceptor{
	
	@Autowired
	UserService userService;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object)
			throws Exception {
		if (request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
		// 从 http 请求头中取出 token
        String token = request.getHeader("token");
        // 如果不是映射到方法直接通过
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        if(method.isAnnotationPresent(LoginToken.class)) {
        	LoginToken loginToken = method.getAnnotation(LoginToken.class);
        	if(loginToken.required()) {
        		return true;
        	}
        }
        
        if(method.isAnnotationPresent(CheckToken.class)) {
        	CheckToken checkToken = method.getAnnotation(CheckToken.class);
        	if(checkToken.required()) {
        		if(token == null) {
        			throw new MyException("请重新登录");
        		}
        		Claims claim = null;
        		try {
        			claim = JwtUtil.parseJWT(token);
        		} catch (Exception e) {
        			e.printStackTrace();
					throw new MyException("访问异常。");
				}
        		
        		// 获取 token 中的 user id
        		if(claim == null || claim.get("id") == null) {
        			throw new MyException("访问异常");
        		}
                Long userId;
                try {
                    String userIdStr = claim.get("id").toString();
                    userId = Long.valueOf(userIdStr);
                } catch (JWTDecodeException j) {
                    throw new MyException("访问异常！请重新登陆");
                }
                
                User user = userService.findById(userId);
                if(user == null) {
                	throw new MyException("用户不存在");
                }
//                User user = new User();
//                user.setId(100l);
//                user.setBalance(1111);
//                user.setOpenid("3333f");
                ThreadLocalUser.getInstance().setUser(user);
        	}
        	return true;
        }
        
        if(StringUtils.isNotBlank(token)) {
        	Claims claim = null;
        	try {
        		claim = JwtUtil.parseJWT(token);
        		// 获取 token 中的 user id
        		if(claim != null && claim.get("id") != null) {
        			String userIdStr = claim.get("id").toString();
        			Long userId = Long.valueOf(userIdStr);
        			
        			User user = userService.findById(userId);
        			if(user != null) {
        				ThreadLocalUser.getInstance().setUser(user);
        			}
        		}
        	} catch (Exception e) {
			}
        }
		return true;
	}
	
	@Override
	public void afterCompletion(
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		ThreadLocalUser.getInstance().remove();
	}
}
